//#########################################################################
//                              WackiEngie
//           Copyright (c) 2014 Marc Wacker. All rights reserved.
//#########################################################################

#include "WeTextureCube.h"

namespace WackiEngine
{


	TextureCube::TextureCube()
	{
		Texture::init(GL_TEXTURE_CUBE_MAP);
	}

	TextureCube::TextureCube(
		GLint format,
		GLsizei width,
		GLsizei height,
		GLenum srcDataFormat,
		GLenum srcDataType,
		const GLvoid *srcDataXp,
		const GLvoid *srcDataXn,
		const GLvoid *srcDataYp,
		const GLvoid *srcDataYn,
		const GLvoid *srcDataZp,
		const GLvoid *srcDataZn
		)
	{
		Texture::init(GL_TEXTURE_CUBE_MAP);
		image(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, width, height, srcDataFormat, srcDataType, srcDataXp);
		image(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, width, height, srcDataFormat, srcDataType, srcDataXn);
		image(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format, width, height, srcDataFormat, srcDataType, srcDataYp);
		image(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format, width, height, srcDataFormat, srcDataType, srcDataYn);
		image(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format, width, height, srcDataFormat, srcDataType, srcDataZp);
		image(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format, width, height, srcDataFormat, srcDataType, srcDataZn);
	}


	void TextureCube::image(
		GLenum face,
		GLint level,
		GLint format,
		GLsizei width,
		GLsizei height,
		GLenum srcDataFormat,
		GLenum srcDataType,
		const GLvoid *srcData
		)
	{
		assert(_handle != GL_ZERO);
		assert((face == GL_TEXTURE_CUBE_MAP_POSITIVE_X) ||
			(face == GL_TEXTURE_CUBE_MAP_NEGATIVE_X) ||
			(face == GL_TEXTURE_CUBE_MAP_POSITIVE_Y) ||
			(face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ||
			(face == GL_TEXTURE_CUBE_MAP_POSITIVE_Z) ||
			(face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z));

		if(format == GL_DEPTH_COMPONENT) {
			switch(srcDataFormat) {
			case GL_DEPTH_COMPONENT:
			case GL_DEPTH_COMPONENT16:
			case GL_DEPTH_COMPONENT24:
			case GL_DEPTH_COMPONENT32:
			case GL_DEPTH_COMPONENT32F:
				// format is ok
				break;
			default:
				srcDataFormat = GL_DEPTH_COMPONENT;
				break;
			}
		}

		glTexImage2D(face, level, format, width, height, 0, srcDataFormat, srcDataType, srcData);

		updateParameters();
	}


	void TextureCube::subImage(
		GLenum face,
		GLint level,
		GLint xOffset,
		GLint yOffset,
		GLsizei width,
		GLsizei height,
		GLenum srcDataFormat,
		GLenum srcDataType,
		const GLvoid *srcData
		)
	{
		assert(_handle != GL_ZERO);
		assert(xOffset >= 0 && xOffset <= _size[0]);
		assert(yOffset >= 0 && xOffset <= _size[1]);
		assert((xOffset + width) <= _size[0]);
		assert((yOffset + height) <= _size[1]);
		assert((face == GL_TEXTURE_CUBE_MAP_POSITIVE_X) ||
			(face == GL_TEXTURE_CUBE_MAP_NEGATIVE_X) ||
			(face == GL_TEXTURE_CUBE_MAP_POSITIVE_Y) ||
			(face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ||
			(face == GL_TEXTURE_CUBE_MAP_POSITIVE_Z) ||
			(face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z));

		glTexSubImage2D(face, level, xOffset, yOffset, width, height, srcDataFormat, srcDataType, srcData);
	}

}